<?php
class Outinvoice {
  function __construct() {
  }

  public function select() {
  
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->outinvoice->rwd;
		if( ($rwd & PERM_BITS::READ_ANY) == 0 ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'oiv_inv_date';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
 
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
        if( $search )
        {
			switch( $_REQUEST["status"] ) {
			case '0': break;
			case '1': $whc[] = "( oiv_paid IS NULL OR oiv_paid = 0 )"; break;
			case '2': $whc[] = "oiv_paid < oiv_amount"; break;
			case '3': $whc[] = "oiv_paid = oiv_amount"; break;
			case '4': $whc[] = "oiv_paid > oiv_amount"; break;
			}
			
            if(isset($_REQUEST["oiv_id"]) && is_numeric($_REQUEST["oiv_id"]) ) {
				$whc[] = "oiv_id=" . $db->quote($_REQUEST["oiv_id"]);
		    }
            
            if(isset($_REQUEST["oiv_cli_id"]) && $_REQUEST["oiv_cli_id"] != "") {
		    	$whc[] = "oiv_cli_id=" . $db->quote($_REQUEST["oiv_cli_id"]);
            }

            if(isset($_REQUEST["cli_name"]) && $_REQUEST["cli_name"] != "") {
		    	$whc[] = "cli_name LIKE " . $db->quote("%".$_REQUEST["cli_name"]."%");
            }

            if(isset($_REQUEST["oiv_build_id"]) && $_REQUEST["oiv_build_id"] != "") {
		    	$whc[] = "oiv_build_id=" . $db->quote($_REQUEST["oiv_build_id"]);
            }

            if(isset($_REQUEST["build_name"]) && $_REQUEST["build_name"] != "") {
		    	$whc[] = "build_name LIKE " . $db->quote("%".$_REQUEST["build_name"]."%");
            }
			
            if(isset($_REQUEST["oiv_inv_date"]) && $_REQUEST["oiv_inv_date"] != "") {
				$bkd = $_REQUEST["oiv_inv_date"];
				$dt = '';
				$dlmpos = strpos( $bkd, '-' ); 
				if( is_bool( $dlmpos ) ) {
					$dt = Tools::date_to_search_str( $bkd );
					if( $dt )
						$whc[] = "oiv_inv_date LIKE " . $db->quote("%".$dt."%");
				}
				else {
					$sdt = Tools::date_to_search_str( substr( $bkd, 0, $dlmpos ) );
					$fdt = Tools::date_to_search_str( substr( $bkd, $dlmpos + 1 ) );
					if( strlen( $sdt ) && strlen( $fdt ) && $fdt > $sdt ) {
						$whc[] = "oiv_inv_date >= " . $db->quote($sdt) .
								" AND oiv_inv_date < " . $db->quote($fdt);
					}
				}
            }
			
            if(isset($_REQUEST["oiv_inv_num"]) && $_REQUEST["oiv_inv_num"] != "") {
		    	$whc[] = "oiv_inv_num LIKE " . $db->quote("%".$_REQUEST["oiv_inv_num"]."%");
            }
			
            if(isset($_REQUEST["oiv_amount"]) && $_REQUEST["oiv_amount"] != "") {
		    	$whc[] = "oiv_amount LIKE " . $db->quote("%".$_REQUEST["oiv_amount"]."%");
            }
			
            if(isset($_REQUEST["oiv_paid"]) && $_REQUEST["oiv_paid"] != "") {
		    	$whc[] = "oiv_paid LIKE " . $db->quote("%".$_REQUEST["oiv_paid"]."%");
            }
			
            if(isset($_REQUEST["oiv_pm_type"]) && $_REQUEST["oiv_pm_type"] != "") {
		    	$whc[] = "oiv_pm_type LIKE " . $db->quote("%".$_REQUEST["oiv_pm_type"]."%");
            }
			
            if( isset($_REQUEST["oiv_dep_id"]) && $_REQUEST["oiv_dep_id"] ) {
		    	$whc[] = "oiv_dep_id=" . $db->quote($_REQUEST["oiv_dep_id"]);
            }

            if(isset($_REQUEST["oiv_content"]) && $_REQUEST["oiv_content"] != "") {
		    	$whc[] = "oiv_content LIKE " . $db->quote("%".$_REQUEST["oiv_content"]."%");
            }
			
            if(isset($_REQUEST["oiv_contract"]) && $_REQUEST["oiv_contract"] != "") {
		    	$whc[] = "oiv_contract LIKE " . $db->quote("%".$_REQUEST["oiv_contract"]."%");
            }
			
            if(isset($_REQUEST["oiv_comment"]) && $_REQUEST["oiv_comment"] != "") {
		    	$whc[] = "oiv_comment LIKE " . $db->quote("%".$_REQUEST["oiv_comment"]."%");
            }
			
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'oiv_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'oiv_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';
		
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);
            
// Получаем количество записей с учетом фильтра
        $join1 = "INNER JOIN clients ON clients.cli_id = outinvoice.oiv_cli_id ";
        $join2 = "INNER JOIN builds ON builds.build_id = outinvoice.oiv_build_id ";
        $join3 = "LEFT JOIN depart ON depart.dep_id = outinvoice.oiv_dep_id ";
        $join4 = "LEFT JOIN (SELECT oip_inv_id, SUM(oip_amount) AS oiv_paid FROM `outinvpays` ".
						"GROUP BY oip_inv_id) AS oipays ON oipays.oip_inv_id = outinvoice.oiv_id ";
						
        $sqlreq = "SELECT COUNT(*) AS count FROM outinvoice ".$join1.$join2.$join4.$whereclaus;
        $recset = $db->query( $sqlreq );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$count = $row['count'];
		$recset->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sqlreq =   "SELECT oiv_id, oiv_inv_date, oiv_amount, oiv_paid, ".
//					"( SELECT SUM(oip_amount) FROM outinvpays WHERE oip_inv_id = oiv_id ) AS oiv_paid, ". 
					"oiv_pm_type, dep_name, oiv_cli_id, cli_name, ".
					"oiv_build_id, build_name, oiv_content, oiv_inv_num, oiv_contract, oiv_comment ".
					"FROM outinvoice ".$join1.$join2.$join3.$join4.$whereclaus." ORDER BY ".$sidx." ".$sord.
		            " LIMIT ".$start.", ".$limit;

		$recset = $db->query($sqlreq);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $recset->fetch(PDO::FETCH_ASSOC)) {
			$oiv_amount = $row['oiv_amount'];
			$oiv_paid = is_null($row['oiv_paid']) ? 0 : $row['oiv_paid'];
			
			if( !$oiv_paid ) $status = 1;
			elseif( $oiv_paid < $oiv_amount ) $status = 2;
			elseif( $oiv_paid == $oiv_amount ) $status = 3;
			elseif( $oiv_paid > $oiv_amount ) $status = 4;
				
			preg_match( '/(\d\d\d\d)-(\d\d)-(\d\d)/', $row['oiv_inv_date'], $dmy );
			$data->rows[$i]['id'] = $row['oiv_id'];
			$data->rows[$i]['cell'] = array(
					$row['oiv_id'],
					$status,
					$dmy[3].'.'.$dmy[2].'.'.$dmy[1],
					$row['oiv_inv_num'],
					$row['oiv_amount'],
					$oiv_paid,
					$row['oiv_pm_type'],
					$row['dep_name'],
					$row['oiv_cli_id'],
				    $row['cli_name'],
					$row['oiv_build_id'],
				    $row['build_name'],
					$row['oiv_content'],
					$row['oiv_contract'],
					$row['oiv_comment']
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
  
  
  public function insert() {

    $oiv_inv_date	= isset($_POST['oiv_inv_date']) ? trim(strip_tags($_POST['oiv_inv_date'])) : '';
    $oiv_inv_num 	= isset($_POST['oiv_inv_num']) ? trim(strip_tags($_POST['oiv_inv_num'])) : '';
    $oiv_amount		= isset($_POST['oiv_amount']) ? trim(strip_tags($_POST['oiv_amount'])) : '';
    $oiv_pm_type	= isset($_POST['oiv_pm_type']) ? trim(strip_tags($_POST['oiv_pm_type'])) : '';
    $oiv_dep_id		= isset($_POST['oiv_dep_id']) ? trim(strip_tags($_POST['oiv_dep_id'])) : '';
    $oiv_cli_id	= isset($_POST['oiv_cli_id']) ? trim(strip_tags($_POST['oiv_cli_id'])) : '';
    $cli_name 		= isset($_POST['cli_name']) ? trim(strip_tags($_POST['cli_name'])) : '';
    $oiv_build_id	= isset($_POST['oiv_build_id']) ? trim(strip_tags($_POST['oiv_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $oiv_content 	= isset($_POST['oiv_content']) ? trim(strip_tags($_POST['oiv_content'])) : '';
    $oiv_contract	= isset($_POST['oiv_contract']) ? trim(strip_tags($_POST['oiv_contract'])) : '';
    $oiv_comment	= isset($_POST['oiv_comment']) ? trim(strip_tags($_POST['oiv_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$oiv_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->outinvoice->rwd;
		if( ($rwd & PERM_BITS::WRITE_OWN) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// oiv_inv_date
		if( $oiv_inv_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата счета.";
		elseif( ( $oiv_inv_date = Tools::check_date($oiv_inv_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата счета указана неправильно.";

// oiv_amount			
		if( $oiv_amount == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана сумма счета.";
		else {
			$oiv_amount = str_replace(',', '.', $oiv_amount);
			if( !is_numeric( $oiv_amount ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана сумма счета.";
		}
			
// oiv_pm_type			
		if( $oiv_pm_type == '' ) $errdata .= ($errdata?'<br>':'')."- Не указан вид платежа.";
		else {
// Проверяем наличие кода платежа в справочнике
			$rs = $db->query('SELECT 1 FROM inctypes WHERE itp_code = '.$db->quote($oiv_pm_type));                  
			if( !$rs->fetch(PDO::FETCH_ASSOC) )
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан вид платежа.';
			$rs->closeCursor();
		}
			
// oiv_dep_id		
		if( !$oiv_dep_id || !ctype_digit($oiv_dep_id) ) 
			$errdata .= ($errdata?'<br>':'')."- Не указано или указано неправильно подразделение.";

// oiv_cli_id  cli_name			
		if( $cli_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указано имя клиента.';
		elseif( !ctype_digit( $oiv_cli_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор клиента.';
		else {
// Проверяем наличие кода клиента в справочнике
			$recset = $db->query('SELECT cli_id FROM clients WHERE cli_id = '.$db->quote($oiv_cli_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор клиента.';
			}
			$recset->closeCursor();
		}
		
// oiv_build_id  build_name
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
		elseif( !ctype_digit( $oiv_build_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
		else {
// Проверяем наличие обьекта в справочнике
			$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($oiv_build_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
			}
			$recset->closeCursor();
		}

// oiv_content
		if( $oiv_content == '' ) $errdata .= ($errdata?'<br>':'').'- Не указано назначение.';
		
// oiv_inv_num
		if( $oiv_inv_num == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан номер счета.';
		
		if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть платеж уже существует
		$oiv_key1 = preg_replace( '/[^0-9]/u', '', $oiv_inv_date );
		$oiv_key2 = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $oiv_inv_num, 'UTF-8') );
		$oiv_key  = substr( $oiv_key1.' '.$oiv_build_id.' '.$oiv_key2, 0, 64);
		
		$sqlreq =	'SELECT oiv_inv_num, build_name, oiv_inv_date FROM outinvoice '.
					'INNER JOIN builds ON builds.build_id = outinvoice.oiv_build_id '.
					'WHERE oiv_key = '.$db->quote($oiv_key);
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			throw new Exception('Счет с номером "'.$row['oiv_inv_num'].'" по объекту "'.$row['build_name'].
				'" за "'.$row['oiv_inv_date'].'" уже существует.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =   'INSERT INTO outinvoice ( oiv_inv_date, oiv_amount, oiv_pm_type, oiv_dep_id, oiv_cli_id, '.
						'oiv_build_id, oiv_content, oiv_inv_num, oiv_contract, oiv_comment, oiv_key, oiv_user_id ) '.
                    'VALUES ('. $db->quote($oiv_inv_date).", ".$db->quote($oiv_amount).", ".$db->quote($oiv_pm_type).", ".		
                                $db->quote($oiv_dep_id).", ".$db->quote($oiv_cli_id).", ".$db->quote($oiv_build_id).", ".	
                                $db->quote($oiv_content).", ".$db->quote($oiv_inv_num).", ".$db->quote($oiv_contract).", ".
                                $db->quote($oiv_comment).", ".$db->quote($oiv_key).", ".$db->quote($oiv_user_id). ")";
												
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  public function update() {
	
    $oiv_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $oiv_inv_date	= isset($_POST['oiv_inv_date']) ? trim(strip_tags($_POST['oiv_inv_date'])) : '';
    $oiv_inv_num 	= isset($_POST['oiv_inv_num']) ? trim(strip_tags($_POST['oiv_inv_num'])) : '';
    $oiv_amount		= isset($_POST['oiv_amount']) ? trim(strip_tags($_POST['oiv_amount'])) : '';
    $oiv_pm_type	= isset($_POST['oiv_pm_type']) ? trim(strip_tags($_POST['oiv_pm_type'])) : '';
    $oiv_dep_id		= isset($_POST['oiv_dep_id']) ? trim(strip_tags($_POST['oiv_dep_id'])) : '';
    $oiv_cli_id		= isset($_POST['oiv_cli_id']) ? trim(strip_tags($_POST['oiv_cli_id'])) : '';
    $cli_name 		= isset($_POST['cli_name']) ? trim(strip_tags($_POST['cli_name'])) : '';
    $oiv_build_id	= isset($_POST['oiv_build_id']) ? trim(strip_tags($_POST['oiv_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $oiv_content 	= isset($_POST['oiv_content']) ? trim(strip_tags($_POST['oiv_content'])) : '';
    $oiv_contract	= isset($_POST['oiv_contract']) ? trim(strip_tags($_POST['oiv_contract'])) : '';
    $oiv_comment	= isset($_POST['oiv_comment']) ? trim(strip_tags($_POST['oiv_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$oiv_user_id = $_SESSION['user_id'];

// Есть ли разрешение на изменение чьей либо записи
		$rwd = $_SESSION['priv']->outinvoice->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
// Все ли данные переданы
		$errdata = "";
		
// oiv_id
		if( $oiv_id == '' )
			throw new Exception("Не указан идентификатор счета.", 1);

// Проверим наличие платежей по этому счету
			$rs = $db->query('SELECT 1 FROM outinvpays WHERE oip_inv_id = '.$db->quote($oiv_id));                  
			if( $rs->fetch(PDO::FETCH_ASSOC) )
				throw new Exception("По данному счету уже имеются платежи. Внесение изменений недопустимо", 1);
			$rs->closeCursor();		

// oiv_inv_date
		if( $oiv_inv_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата счета.";
		elseif( ( $oiv_inv_date = Tools::check_date($oiv_inv_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата счета указана неправильно.";

// oiv_amount			
		if( $oiv_amount == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана сумма счета.";
		else {
			$oiv_amount = str_replace(',', '.', $oiv_amount);
			if( !is_numeric( $oiv_amount ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана сумма счета.";
		}
			
// oiv_pm_type			
		if( $oiv_pm_type == '' ) $errdata .= ($errdata?'<br>':'')."- Не указан вид платежа.";
		else {
// Проверяем наличие кода платежа в справочнике
			$rs = $db->query('SELECT 1 FROM inctypes WHERE itp_code = '.$db->quote($oiv_pm_type));                  
			if( !$rs->fetch(PDO::FETCH_ASSOC) )
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан вид платежа.';
			$rs->closeCursor();
		}
			
// oiv_dep_id		
		if( !$oiv_dep_id || !ctype_digit($oiv_dep_id) ) 
			$errdata .= ($errdata?'<br>':'')."- Не указано или указано неправильно подразделение.";

// oiv_cli_id  cli_name			
		if( $cli_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указано имя клиента.';
		elseif( !ctype_digit( $oiv_cli_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор клиента.';
		else {
// Проверяем наличие кода клиента в справочнике
			$recset = $db->query('SELECT cli_id FROM clients WHERE cli_id = '.$db->quote($oiv_cli_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор клиента.';
			}
			$recset->closeCursor();
		}
		
// oiv_build_id  build_name
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
		elseif( !ctype_digit( $oiv_build_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
		else {
// Проверяем наличие обьекта в справочнике
			$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($oiv_build_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
			}
			$recset->closeCursor();
		}
		
// oiv_content
		if( $oiv_content == '' ) $errdata .= ($errdata?'<br>':'').'- Не указано назначение.';
		
// oiv_inv_num
		if( $oiv_inv_num == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан номер счета.';
		
// Если есть ошибки - можно закончить
		if( $errdata ) throw new Exception($errdata, 1);
		
// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'oiv_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'oiv_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND oiv_id = '.$db->quote($oiv_id);
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM outinvoice WHERE '.$where.' LIMIT 1';
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row['count'] ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Может быть объект с указаным именем уже существует
		$oiv_key1 = preg_replace( '/[^0-9]/u', '', $oiv_inv_date );
		$oiv_key2 = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $oiv_inv_num, 'UTF-8') );
		$oiv_key  = substr( $oiv_key1.' '.$oiv_build_id.' '.$oiv_key2, 0, 64);
		
		$sqlreq =	'SELECT oiv_inv_num, build_name, oiv_inv_date FROM outinvoice '.
					'INNER JOIN builds ON builds.build_id = outinvoice.oiv_build_id '.
					'WHERE oiv_key = '.$db->quote($oiv_key).' AND '.
							'oiv_id != '.$db->quote($oiv_id);
							
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			throw new Exception('Счет с номером "'.$row['oiv_inv_num'].'" по объекту "'.$row['build_name'].
				'" за "'.$row['oiv_inv_date'].'" уже существует.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =   'UPDATE outinvoice SET '.
						'oiv_inv_date = '. $db->quote($oiv_inv_date).', '.
						'oiv_inv_num = '.	$db->quote($oiv_inv_num).", ".
						'oiv_amount = '.	$db->quote($oiv_amount).", ".
						'oiv_pm_type = '.	$db->quote($oiv_pm_type).", ".
						'oiv_dep_id = '.	$db->quote($oiv_dep_id).", ".
						'oiv_cli_id = '.	$db->quote($oiv_cli_id).", ".
						'oiv_build_id = '.	$db->quote($oiv_build_id).", ".
						'oiv_content = '.	$db->quote($oiv_content).", ".
						'oiv_contract = '.	$db->quote($oiv_contract).", ".
						'oiv_comment = '.	$db->quote($oiv_comment).", ".
						'oiv_key = '.		$db->quote($oiv_key)." ".
                    'WHERE oiv_id = '.$db->quote($oiv_id);
												
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
  
  
  public function delete() {
    $errmess = "";
	$errcode = 0;
		
    $oiv_ids = (isset($_REQUEST['id']) && $_REQUEST['id'] != '') ?
        explode(",", $_REQUEST["id"], 100) : array();

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли разрешение на удаление хоть какой либо записи
		$rwd = $_SESSION['priv']->outinvoice->rwd;
		if( ($rwd & PERM_BITS::DELETE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
        if (!Tools::is_numeric_array( $oiv_ids ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$oiv_id_list = implode(',', $oiv_ids);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на удаление этих записей
		if( $rwd & PERM_BITS::DELETE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::DELETE_GRP ) 
			$where = 'oiv_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::DELETE_OWN ) $where = 'oiv_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND oiv_id IN ('.$oiv_id_list.')';
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM outinvoice WHERE '.$where;
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row['count'] != count($oiv_ids) ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Проверим наличие платежей по этому счету
		$rs = $db->query('SELECT 1 FROM outinvpays WHERE oip_inv_id IN ('.$oiv_id_list.')');                  
		if( $rs->fetch(PDO::FETCH_ASSOC) )
			throw new Exception("По одному или нескольким счетам уже имеются платежи. Удаление этих счетов недопустимо", 1);
		$rs->closeCursor();		

// Удаляем записи из таблицы
        $sqlreq = "DELETE FROM outinvoice WHERE oiv_id IN (".$oiv_id_list.")";
        $db->exec($sqlreq);
	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
  
  public function getdeplist() {
	$errcode = 0;
	$errmess = '';
	$data = array();
	
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Открываем базу данных
		$db = App::me()->dbOpen();	
		$rs = $db->query("SELECT * FROM depart");                  
		while($row = $rs->fetchObject()) {
			$unit = new stdClass;
			$unit->value = $row->dep_id;
			$unit->name = $row->dep_name;
			$data[] = $unit;
		}
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}
 
	return array('errcode'=>$errcode,'errmess'=>$errmess,'data'=>$data);
  }
 

  public function paylist() {
  
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->outinvpays->rwd;
		if( ($rwd & PERM_BITS::READ_ANY) == 0 ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'oip_ord_date';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
 
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
		if( !isset($_REQUEST["oiv_id"]) && !ctype_digit($_REQUEST["oiv_id"]) )
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
		
		$whc[] = "oip_inv_id=" . $db->quote($_REQUEST["oiv_id"]);
		
        if( $search )
        {
            if(isset($_REQUEST["oip_ord_date"]) && $_REQUEST["oip_ord_date"] != "") {
				$bkd = $_REQUEST["oip_ord_date"];
				$dt = '';
				$dlmpos = strpos( $bkd, '-' ); 
				if( is_bool( $dlmpos ) ) {
					$dt = Tools::date_to_search_str( $bkd );
					if( $dt )
						$whc[] = "oip_ord_date LIKE " . $db->quote("%".$dt."%");
				}
				else {
					$sdt = Tools::date_to_search_str( substr( $bkd, 0, $dlmpos ) );
					$fdt = Tools::date_to_search_str( substr( $bkd, $dlmpos + 1 ) );
					if( strlen( $sdt ) && strlen( $fdt ) && $fdt > $sdt ) {
						$whc[] = "oip_ord_date >= " . $db->quote($sdt) .
								" AND oip_ord_date < " . $db->quote($fdt);
					}
				}
            }
			
            if(isset($_REQUEST["oip_ord_num"]) && $_REQUEST["oip_ord_num"] != "") {
		    	$whc[] = "oip_ord_num LIKE " . $db->quote("%".$_REQUEST["oip_ord_num"]."%");
            }
			
            if(isset($_REQUEST["oip_amount"]) && $_REQUEST["oip_amount"] != "") {
		    	$whc[] = "oip_amount LIKE " . $db->quote("%".$_REQUEST["oip_amount"]."%");
            }
			
            if(isset($_REQUEST["oiv_comment"]) && $_REQUEST["oiv_comment"] != "") {
		    	$whc[] = "oiv_comment LIKE " . $db->quote("%".$_REQUEST["oiv_comment"]."%");
            }
			
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'oip_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'oip_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';
		
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);
            
// Получаем количество записей с учетом фильтра
        $sqlreq = "SELECT COUNT(*) AS count FROM outinvpays ".$whereclaus;
        $recset = $db->query( $sqlreq );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$count = $row['count'];
		$recset->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sqlreq =   "SELECT oip_id, oip_inv_id, oip_ord_date, oip_ord_num, oip_amount, oip_comment ".
					"FROM outinvpays ".$whereclaus." ORDER BY ".$sidx." ".$sord.
		            " LIMIT ".$start.", ".$limit;

		$recset = $db->query($sqlreq);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $recset->fetch(PDO::FETCH_ASSOC)) {
		
			$status = 0;
				
			preg_match( '/(\d\d\d\d)-(\d\d)-(\d\d)/', $row['oip_ord_date'], $dmy );
			$data->rows[$i]['id'] = $row['oip_id'];
			$data->rows[$i]['cell'] = array(
					$row['oip_id'],
					$status,
					$dmy[3].'.'.$dmy[2].'.'.$dmy[1],
					$row['oip_ord_num'],
					$row['oip_amount'],
					$row['oip_comment']
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
   
  public function payinsert() {

    $oip_inv_id		= isset($_POST['oiv_id']) ? trim(strip_tags($_POST['oiv_id'])) : '';
    $oip_ord_date 	= isset($_POST['oip_ord_date']) ? trim(strip_tags($_POST['oip_ord_date'])) : '';
    $oip_ord_num	= isset($_POST['oip_ord_num']) ? trim(strip_tags($_POST['oip_ord_num'])) : '';
    $oip_amount		= isset($_POST['oip_amount']) ? trim(strip_tags($_POST['oip_amount'])) : '';
    $oip_comment	= isset($_POST['oip_comment']) ? trim(strip_tags($_POST['oip_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$oip_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->outinvpays->rwd;
		if( ($rwd & PERM_BITS::WRITE_OWN) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// oip_inv_id
		if( !$oip_inv_id )	throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
		else {
			$rs = $db->query( 'SELECT 1 FROM outinvoice WHERE oiv_id = '.$db->quote($oip_inv_id) );
			$row = $rs->fetch(PDO::FETCH_ASSOC);
			if( ! $row  ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
			$rs->closeCursor();			
		}
		
// oip_ord_date
		if( $oip_ord_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата платежа.";
		elseif( ( $oip_ord_date = Tools::check_date($oip_ord_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата платежа указана неправильно.";

// oip_ord_num
		if( $oip_ord_num == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан номер платежа.';
		
// oip_amount			
		if( $oip_amount == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана сумма платежа.";
		else {
			$oip_amount = str_replace(',', '.', $oip_amount);
			if( !is_numeric( $oip_amount ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана сумма платежа.";
		}
					
// Может быть платеж уже существует
		$oip_key1 = preg_replace( '/[^0-9]/u', '', $oip_ord_date );
		$oip_key2 = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $oip_ord_num, 'UTF-8') );
		$oip_key  = substr( $oip_key1.' '.$oip_inv_id.' '.$oip_key2, 0, 64);
		
		$rs = $db->query( 'SELECT oip_ord_num, oip_ord_date FROM outinvpays WHERE oip_key = '.$db->quote($oip_key) );
		if( $row = $rs->fetch(PDO::FETCH_ASSOC) )
			throw new Exception('Платеж с номером "'.$row['oip_ord_num'].'" от "'.
						Tools::str_iso2local_date($row['oip_ord_date']).'" по данному счету уже существует.', 1);
		$rs->closeCursor();

// Пишем данные
        $sql =	'INSERT INTO outinvpays SET '.
					'oip_inv_id = '.$db->quote($oip_inv_id).', '.
					'oip_ord_date = '.$db->quote($oip_ord_date).', '.
					'oip_ord_num = '.$db->quote($oip_ord_num).', '.
					'oip_amount = '.$db->quote($oip_amount).', '.
					'oip_comment = '.$db->quote($oip_comment).', '.
					'oip_key = '.$db->quote($oip_key).', '.
					'oip_user_id = '.$db->quote($oip_user_id);
												
		$db->exec($sql);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  
  public function payupdate() {

    $oip_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $oip_inv_id		= isset($_POST['oiv_id']) ? trim(strip_tags($_POST['oiv_id'])) : '';
    $oip_ord_date 	= isset($_POST['oip_ord_date']) ? trim(strip_tags($_POST['oip_ord_date'])) : '';
    $oip_ord_num	= isset($_POST['oip_ord_num']) ? trim(strip_tags($_POST['oip_ord_num'])) : '';
    $oip_amount		= isset($_POST['oip_amount']) ? trim(strip_tags($_POST['oip_amount'])) : '';
    $oip_comment	= isset($_POST['oip_comment']) ? trim(strip_tags($_POST['oip_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$oip_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->outinvpays->rwd;
		if( ($rwd & PERM_BITS::WRITE_OWN) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// oip_id & oip_inv_id
		if( $oip_id && $oip_inv_id ) {
			// Payments is related to this invoice
			$rs = $db->query( 'SELECT 1 FROM outinvpays WHERE oip_inv_id = '.$db->quote($oip_inv_id).
								' AND oip_id = '.$db->quote($oip_id));
			if( ! $rs->fetch(PDO::FETCH_ASSOC) ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
			$rs->closeCursor();			
		}
		else
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);


// oip_ord_date
		if( $oip_ord_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата платежа.";
		elseif( ( $oip_ord_date = Tools::check_date($oip_ord_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата платежа указана неправильно.";

// oip_ord_num
		if( $oip_ord_num == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан номер платежа.';
		
// oip_amount			
		if( $oip_amount == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана сумма платежа.";
		else {
			$oip_amount = str_replace(',', '.', $oip_amount);
			if( !is_numeric( $oip_amount ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана сумма платежа.";
		}
					
// Может быть платеж уже существует
		$oip_key1 = preg_replace( '/[^0-9]/u', '', $oip_ord_date );
		$oip_key2 = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $oip_ord_num, 'UTF-8') );
		$oip_key  = substr( $oip_key1.' '.$oip_inv_id.' '.$oip_key2, 0, 64);
		
		$rs = $db->query( 'SELECT oip_ord_num, oip_ord_date FROM outinvpays WHERE oip_key = '.$db->quote($oip_key).
					' AND oip_id != '.$db->quote($oip_id) );
		if( $row = $rs->fetch(PDO::FETCH_ASSOC) )
			throw new Exception('Платеж с номером "'.$row['oip_ord_num'].'" от "'.
						Tools::str_iso2local_date($row['oip_ord_date']).'" по данному счету уже существует.', 1);
		$rs->closeCursor();

// Пишем данные
        $sql =	'UPDATE outinvpays SET '.
					'oip_ord_date = '.$db->quote($oip_ord_date).', '.
					'oip_ord_num = '.$db->quote($oip_ord_num).', '.
					'oip_amount = '.$db->quote($oip_amount).', '.
					'oip_comment = '.$db->quote($oip_comment).', '.
					'oip_key = '.$db->quote($oip_key).' '.
				'WHERE oip_id = '.$db->quote($oip_id);
												
		$db->exec($sql);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

  public function paydelete() {
    $errmess = "";
	$errcode = 0;
		
    $oip_ids = (isset($_REQUEST['id']) && $_REQUEST['id'] != '') ?
        explode(",", $_REQUEST["id"], 100) : array();

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли разрешение на удаление хоть какой либо записи
		$rwd = $_SESSION['priv']->outinvpays->rwd;
		if( ($rwd & PERM_BITS::DELETE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
        if (!Tools::is_numeric_array( $oip_ids ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$oip_id_list = implode(',', $oip_ids);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на удаление этих записей
		if( $rwd & PERM_BITS::DELETE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::DELETE_GRP ) 
			$where = 'oip_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::DELETE_OWN ) $where = 'oip_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND oip_id IN ('.$oip_id_list.')';
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM outinvpays WHERE '.$where;
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row['count'] != count($oip_ids) ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Удаляем записи из таблицы
        $sqlreq = "DELETE FROM outinvpays WHERE oip_id IN (".$oip_id_list.")";
        $db->exec($sqlreq);
	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
  
  public function fullpaylist() {
  
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$rwd = $_SESSION['priv']->outinvpays->rwd;
		if( ($rwd & PERM_BITS::READ_ANY) == 0 ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'oip_ord_date';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
 
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
		
        if( $search )
        {
            if(isset($_REQUEST["oip_ord_date"]) && $_REQUEST["oip_ord_date"] != "") {
				$bkd = $_REQUEST["oip_ord_date"];
				$dt = '';
				$dlmpos = strpos( $bkd, '-' ); 
				if( is_bool( $dlmpos ) ) {
					$dt = Tools::date_to_search_str( $bkd );
					if( $dt )
						$whc[] = "oip_ord_date LIKE " . $db->quote("%".$dt."%");
				}
				else {
					$sdt = Tools::date_to_search_str( substr( $bkd, 0, $dlmpos ) );
					$fdt = Tools::date_to_search_str( substr( $bkd, $dlmpos + 1 ) );
					if( strlen( $sdt ) && strlen( $fdt ) && $fdt > $sdt ) {
						$whc[] = "oip_ord_date >= " . $db->quote($sdt) .
								" AND oip_ord_date < " . $db->quote($fdt);
					}
				}
            }
			
            if(isset($_REQUEST["oip_ord_num"]) && $_REQUEST["oip_ord_num"] != "") {
		    	$whc[] = "oip_ord_num LIKE " . $db->quote("%".$_REQUEST["oip_ord_num"]."%");
            }
			
            if(isset($_REQUEST["oip_amount"]) && $_REQUEST["oip_amount"] != "") {
		    	$whc[] = "oip_amount LIKE " . $db->quote("%".$_REQUEST["oip_amount"]."%");
            }
			
            if(isset($_REQUEST["oip_inv_id"]) && $_REQUEST["oip_inv_id"] != "") {
		    	$whc[] = "oip_inv_id = " . $db->quote($_REQUEST["oip_inv_id"]);
            }
			
            if(isset($_REQUEST["oiv_inv_date"]) && $_REQUEST["oiv_inv_date"] != "") {
				$bkd = $_REQUEST["oiv_inv_date"];
				$dt = '';
				$dlmpos = strpos( $bkd, '-' ); 
				if( is_bool( $dlmpos ) ) {
					$dt = Tools::date_to_search_str( $bkd );
					if( $dt )
						$whc[] = "oiv_inv_date LIKE " . $db->quote("%".$dt."%");
				}
				else {
					$sdt = Tools::date_to_search_str( substr( $bkd, 0, $dlmpos ) );
					$fdt = Tools::date_to_search_str( substr( $bkd, $dlmpos + 1 ) );
					if( strlen( $sdt ) && strlen( $fdt ) && $fdt > $sdt ) {
						$whc[] = "oiv_inv_date >= " . $db->quote($sdt) .
								" AND oiv_inv_date < " . $db->quote($fdt);
					}
				}
            }
			
            if(isset($_REQUEST["oiv_inv_num"]) && $_REQUEST["oiv_inv_num"] != "") {
		    	$whc[] = "oiv_inv_num LIKE " . $db->quote("%".$_REQUEST["oiv_inv_num"]."%");
            }
			
            if(isset($_REQUEST["build_name"]) && $_REQUEST["build_name"] != "") {
		    	$whc[] = "build_name LIKE " . $db->quote("%".$_REQUEST["build_name"]."%");
            }
			
            if(isset($_REQUEST["oiv_comment"]) && $_REQUEST["oiv_comment"] != "") {
		    	$whc[] = "oiv_comment LIKE " . $db->quote("%".$_REQUEST["oiv_comment"]."%");
            }
			
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'oip_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'oip_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';
		
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);
        
		$join1 = 'LEFT JOIN outinvoice ON oiv_id = oip_inv_id ';
        $join2 = "LEFT JOIN builds ON build_id = oiv_build_id ";
		
// Получаем количество записей с учетом фильтра
        $sqlreq = "SELECT COUNT(*) AS count FROM outinvpays ".$join1.$join2.$whereclaus;
        $recset = $db->query( $sqlreq );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$count = $row['count'];
		$recset->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sqlreq =   "SELECT oip_id, oip_inv_id, oip_ord_date, oip_ord_num, oip_amount, ".
							"oiv_inv_date, oiv_inv_num, build_name, oip_comment ".
					"FROM outinvpays ".$join1.$join2.$whereclaus." ORDER BY ".$sidx." ".$sord.
		            " LIMIT ".$start.", ".$limit;

		$recset = $db->query($sqlreq);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $recset->fetch(PDO::FETCH_ASSOC)) {
		
			$status = 0;
				
			preg_match( '/(\d\d\d\d)-(\d\d)-(\d\d)/', $row['oip_ord_date'], $dmy1 );
			preg_match( '/(\d\d\d\d)-(\d\d)-(\d\d)/', $row['oiv_inv_date'], $dmy2 );
			$data->rows[$i]['id'] = $row['oip_id'];
			$data->rows[$i]['cell'] = array(
					$row['oip_id'],
					$status,
					$dmy1[3].'.'.$dmy1[2].'.'.$dmy1[1],
					$row['oip_ord_num'],
					$row['oip_amount'],
					$dmy2[3].'.'.$dmy2[2].'.'.$dmy2[1],
					$row['oiv_inv_num'],
					$row['build_name'],
					$row['oip_comment']
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }
   
}
?>